/// <reference path="../lib/lib.ts" />

class Game {
 
    private static _instance : Game = null;
    
    private _world : b2World;
    private _statics : b2Body;
    private _stage : Stage;
    private _canvas : any;
    private _unit : Unit;
    
    private _lastUpdateTime : number;
 
    constructor() {
    
        if(Game._instance){
            throw new Error("Error: Singleton");
        }
        
        this._canvas = document.getElementById("canvas");
        this._world = new b2World(new b2Vec2(0, 0), true);
        this._stage = new Stage(this._canvas);
        
	    var bodyDef = new b2BodyDef();
	    bodyDef.type = b2Body.b2_staticBody;
		bodyDef.position.x = 0;
		bodyDef.position.y = 0;
        
        this._statics = this._world.CreateBody(bodyDef);
        this._statics.SetAwake(false);
        
	    var debugDraw = new b2DebugDraw();
	    var canv : any = document.getElementById("debugCanvas");
	    debugDraw.SetSprite(canv.getContext("2d"));
	    debugDraw.SetFillAlpha(0.3);
	    debugDraw.SetLineThickness(1.0);
	    debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
	    this._world.SetDebugDraw(debugDraw);
        
        this._lastUpdateTime = Date.now();
        requestAnimationFrame(this.update);
        
        Game._instance = this;
    }
    
    public createStatic(fixDef : b2FixtureDef, skin : DisplayObject) {
    	this._stage.addChild(skin);
    	return this._statics.CreateFixture(fixDef);
    }
    
    public createDynamic(bodyDef : b2BodyDef, skin : DisplayObject) : b2Body {
    	this._stage.addChild(skin);
    	return this._world.CreateBody(bodyDef);
    }
    
    public createUnit(x : number, y : number) {
    	this._unit = new Unit(x, y);
    }
    
    public unitMove(dir : number) {
    	this._unit.Move(dir);
    }
    
    public unitStop(){
    	this._unit.Stop();
    } 
    
    public startMap(mapName : string) {
    	var map = _maps[mapName];
    	var blocks = map["PlateBlocks"]; 
    	for(var i = 0; i < blocks.length; i++) {
    		var pblock = new PlateBlock(blocks[i][0], blocks[i][1]);
    	}
    	var blocks = map["BrickBlocks"]; 
    	for(var i = 0; i < blocks.length; i++) {
    		var bblock = new BrickBlock(blocks[i][0], blocks[i][1]);
    	}
    }
    
    private update() {
    	var now = Date.now();
		var dt = now - Game.getInstance()._lastUpdateTime;
		Game.getInstance()._lastUpdateTime = now;
		
    	Game.getInstance()._world.Step(1, 10, 10);
	   	Game.getInstance()._world.DrawDebugData();
    	
    	Game.getInstance()._unit.update();
    	
    	Game.getInstance()._stage.update();
    	requestAnimationFrame(Game.getInstance().update);
    }
 
    public static getInstance() : Game {
        if(Game._instance === null) {
            Game._instance = new Game();
        }
        return Game._instance;
    }
 
}